package options

import (
	"errors"
	"fmt"
	"github.com/spf13/pflag"
	"strings"
)

// DiscoveryOptions 用于服务发现的注册中心的配置对象
type DiscoveryOptions struct {
	// Address , registry center host and port ,like 127.0.0.1:8500
	Address string `mapstructure:"address" json:"address,omitempty"`
	// Scheme , like http or https
	Scheme string `mapstructure:"scheme"  json:"scheme,omitempty"`
	// ServerName , server name
	ServerName string `mapstructure:"server-name"  json:"server-name,omitempty"`
	// Type , discovery type
	Type RegistryDiscoveryType `mapstructure:"type"  json:"type,omitempty"`
}

func NewDiscoveryOptions() *DiscoveryOptions {
	return &DiscoveryOptions{
		Address:    "127.0.0.1:8500",
		Scheme:     "http",
		ServerName: "",
		Type:       RegistryDiscoveryTypeNativeType,
	}
}

func (o *DiscoveryOptions) AddFlags(fs *pflag.FlagSet) {
	fs.StringVar(&o.Address, "discovery.address", o.Address, "discovery address .")
	fs.StringVar(&o.Scheme, "discovery.scheme", o.Scheme, "discovery scheme.")
	fs.StringVar(&o.ServerName, "discovery.server-name", o.ServerName, "discovery server name.")
	fs.StringVar((*string)(&o.Type), "discovery.type", string(o.Type), "discovery type.")
}

func (o *DiscoveryOptions) Validate() error {
	if o.Address == "" {
		return errors.New("address is empty")
	}
	if o.Scheme == "" {
		return errors.New("scheme is empty")
	}
	if o.ServerName == "" {
		return errors.New("server-name is empty")
	}
	if o.Type == "" {
		return errors.New("type is empty")
	}
	DiscoveryType := strings.ToLower(string(o.Type))
	switch DiscoveryType {
	case string(RegistryDiscoveryTypeNativeType):
	case string(RegistryDiscoveryTypeConsul):
	case string(RegistryDiscoveryTypeEtcd):
	case string(RegistryDiscoveryTypeEureka):
	case string(RegistryDiscoveryTypeKubernetes):
	case string(RegistryDiscoveryTypeNacos):
	case string(RegistryDiscoveryTypeZookeeper):
	default:
		errMsg := fmt.Sprintf("not supported discovery type:%s", DiscoveryType)
		return errors.New(errMsg)
	}
	return nil
}
